#ifndef __GKOS_LIST_H
#define __GKOS_LIST_H
#include "lib/global.h"

#define offset (struct_type, member) (int)(&((struct_type*)0)->member)
#define elem2entry(struct_type, struct_member_name, elem_ptr) \
    (struct_type*) ((int)elem_ptr - offset(struct_type, struct_member_name))

typedef uint32_t ListFunction(struct list_elem *, int); 

struct list_elem {
    struct list_elem *prev;
    struct list_elem *next;
};

struct list {
    struct list_elem head;
    struct list_elem tail;
};

void list_init(struct list *list);
void list_insert_before(struct list_elem *before, struct list_elem *elem);
void list_push_front(struct list *list, struct list_elem *elem);
void list_push_back(struct list *list, struct list_elem *elem);
void list_remove(struct list_elem *elem);
struct list_elem *list_pop_front(struct list *list);
struct list_elem *list_pop_back(struct list *list);
uint32_t list_empty(struct list *list);
uint32_t list_size(struct list *list);
struct list_elem *list_begin(struct list *list);
struct list_elem *list_end(struct list *list);
struct list_elem *list_next(struct list_elem *elem);
struct list_elem *list_prev(struct list_elem *elem);
struct list_elem *list_traversal(struct list *list, ListFunction func, int arg);
uint32_t elem_find(struct list *list, struct list_elem *obj_elem);

#endif